const gulp = require('gulp');
const gulpif = require('gulp-if');
const through = require('through2');
const watch = require('gulp-watch');
const uglify = require('gulp-uglify');
const notify = require('gulp-notify');
const plumber = require('gulp-plumber');
const htmlmin = require('gulp-htmlmin');
const minifycss = require('gulp-minify-css');
const changed = require('gulp-changed');
const revHash = require('rev-hash');
const autoprefixer = require('gulp-autoprefixer');

const { entry = {}, output = {} } = require('./package.json').config;
const NODE_ENV = process.argv.splice(2)[0] === '--prod';
const hashMap = {};


function errrHandler(e) {
    console.info(e)
};

function getHash() {
    return through.obj(function(file, encoding, callback) {

        if (!file.isBuffer()) {
            return callback(null, file);
        }

        //自动适配当前系统的斜杠模式
        let pathArray = file.path.split('//');

        if (!pathArray.length <= 1) {
            pathArray = file.path.split('\\');
        }

        //生成本地文件的hash表，统一用 `/` 作为分割（HTML中的路径默认都是 /）
        if (pathArray.length > 1) {
            hashMap[pathArray[pathArray.length - 2] + '/' + pathArray[pathArray.length - 1]] = revHash(file.contents);
        }

        return callback(null, file);

    });

}

function handleVer() {

    return through.obj(function(file, encoding, callback) {

        if (!file.isBuffer()) {
            return callback(null, file);
        }

        let contents = String(file.contents);
        let pattern = null;

        for (var i in hashMap) {
            pattern = new RegExp(i, 'gi');
            contents = contents.replace(pattern, i + '?v=' + hashMap[i]);
        }

        file.contents = new Buffer(contents);
        return callback(null, file);

    });
}

//js生成文件hash编码并生成rev-manifest.json文件名对照映射
gulp.task('revJs', function() {
    return gulp.src(entry._JS_RES_).pipe(getHash())
});

//CSS生成文件hash编码并生成rev-manifest.json文件名对照映射
gulp.task('revCss', function() {
    return gulp.src(entry._CSS_RES_).pipe(getHash())
});

//Image生成文件hash编码并生成rev-manifest.json文件名对照映射
gulp.task('revImage', function() {
    return gulp.src(entry._IMAGE_RES).pipe(getHash())
});

gulp.task('minifycss', function() {
    return gulp.src(entry._CSS_RES_) //设置css
        .pipe(changed(output.dist))
        .pipe(gulpif(!NODE_ENV, watch(entry._CSS_RES_))) //压缩文件 
        .pipe(plumber({ errorHandler: errrHandler }))
        .pipe(gulpif(NODE_ENV, autoprefixer({
            browsers: ['last 2 versions'],
            cascade: false //  是否美化属性值 
        }))) //压缩文件
        .pipe(gulpif(NODE_ENV, handleVer()))
        .pipe(gulpif(NODE_ENV, minifycss())) //压缩文件
        .pipe(gulp.dest(output.dist)) //输出文件目录
        .pipe(notify({ message: 'css task ok' })); //提示成功
});

gulp.task('minifyjs', function() {
    return gulp.src(entry._JS_RES_) //设置css
        .pipe(changed(output.dist))
        .pipe(gulpif(!NODE_ENV, watch(entry._JS_RES_))) //压缩文件 
        .pipe(plumber({ errorHandler: errrHandler }))
        .pipe(gulpif(NODE_ENV, uglify())) //压缩文件 
        .pipe(gulp.dest(output.dist)) //输出文件目录
        .pipe(notify({ message: 'js task ok' })); //提示成功
});

gulp.task('htmlmin', function() {

    let options = {
        removeComments: true, //清除HTML注释
        collapseWhitespace: true, //压缩HTML
        collapseBooleanAttributes: false, //省略布尔属性的值 <input checked="true"/> ==> <input />
        removeEmptyAttributes: false, //删除所有空格作属性值 <input id="" /> ==> <input />
        removeScriptTypeAttributes: true, //删除<script>的type="text/javascript"
        removeStyleLinkTypeAttributes: true, //删除<style>和<link>的type="text/css"
        minifyJS: true, //压缩页面JS
        minifyCSS: true //压缩页面CSS
    };

    return gulp.src(entry._FTL_RES_)
        .pipe(changed(output.dist))
        .pipe(gulpif(!NODE_ENV, watch(entry._FTL_RES_))) //压缩文件 
        .pipe(plumber({ errorHandler: errrHandler }))
        .pipe(gulpif(NODE_ENV, handleVer()))
        .pipe(gulpif(NODE_ENV, htmlmin(options)))
        .pipe(gulp.dest(output.dist))
        .pipe(notify({ message: 'html task ok' })); //提示成功
});

if (NODE_ENV) {
    gulp.task('default', gulp.series(gulp.parallel('revJs', 'revCss', 'revImage'), gulp.parallel('minifycss', 'minifyjs', 'htmlmin')));
} else {
    gulp.task('default', gulp.parallel('minifycss', 'minifyjs', 'htmlmin'));
}